'''
Seal V1: Deprecated
'''

import serial
import time
import re

class TapingMachineController:
    def __init__(self, port='/dev/Seal', baudrate=19200):
        """
        初始化串口连接。
        
        :param port: 设备的串口号，默认'/dev/ttyUSB0'
        :param baudrate: 波特率，默认19200
        """
        self.ser = serial.Serial(port, baudrate, bytesize=serial.EIGHTBITS,
                                 parity=serial.PARITY_NONE, stopbits=serial.STOPBITS_ONE, timeout=1)
        time.sleep(2)  # 等待串行连接初始化
        
    def _calculate_checksum(self, cmd_str):
        """示例中校验和固定为'zz'"""
        return 'zz'

    def send_command(self, command, index='00', params=None):
        """
        发送命令给设备并接收响应。
        
        :param command: 命令代码
        :param index: 命令索引，默认'00'
        :param params: 参数列表
        :return: 响应字符串
        """
        if params is None:
            params = []
        
        # 构造命令字符串
        cmd_str = f"*{index}{command}="
        for param in params:
            cmd_str += f"{param},"
        cmd_str = cmd_str.rstrip(',') + "!"
        
        checksum = self._calculate_checksum(cmd_str)
        full_cmd = f"{cmd_str[:-1]}{checksum}!"  # 将校验和插入到命令中
        
        print(f"[DEBUG] Sending command: {full_cmd}")
        self.ser.write(full_cmd.encode('ascii'))
        
        # 等待并验证确认响应
        confirmation_response = self._wait_for_confirmation(index=index)
        if not confirmation_response:
            raise RuntimeError("Failed to receive confirmation response after sending command.")
        
        # 确认响应成功后延时 0.1 秒
        time.sleep(0.1)

        return confirmation_response

    def _parse_response(self, response):
        """
        解析设备响应，去除校验和并提取有效数据。
        
        :param response: 原始响应字符串
        :return: 去除校验和的有效数据部分
        """
        print(f"[DEBUG] Parsing response: {response}")
        
        # 使用正则表达式去掉校验和部分
        match = re.match(r"^(.*?)(zz|yy)!$", response.strip())
        if match:
            parsed_response = match.group(1)
            print(f"[DEBUG] Parsed response (without checksum): {parsed_response}")
            return parsed_response
        else:
            raise ValueError(f"Invalid response format: {response}")

    def _wait_for_confirmation(self, index='00', timeout=1):
        """
        等待并验证确认响应。
        
        :param index: 命令索引
        :param timeout: 超时时间（秒）
        :return: 确认响应是否成功
        """
        start_time = time.time()
        while time.time() - start_time < timeout:
            raw_response = self.ser.read_until(b'!')
            decoded_response = raw_response.decode('ascii').strip()
            print(f"[DEBUG] Received raw confirmation response: {decoded_response}")
            
            # 检查响应格式是否为 *Y<index>zz!
            expected_response = f"*Y{index}zz!"
            if decoded_response == expected_response:
                print(f"[INFO] Confirmation received: {decoded_response}")
                return True
        
        print(f"[ERROR] Timeout waiting for confirmation response.")
        return False

    def get_device_status(self):
        """
        获取设备主动反馈的状态信息。
        
        :return: 解析后的状态字典
        """
        try:
            # 监听设备反馈的状态信息
            raw_response = self.ser.read_until(b'!')
            decoded_response = raw_response.decode('ascii')
            print(f"[DEBUG] Listening to device status feedback: {decoded_response}")
            
            # 解析响应
            parsed_response = self._parse_response(decoded_response)
            
            # 检查响应是否为正常状态响应
            if not parsed_response.startswith('*T'):
                raise ValueError(f"Unexpected status response: {parsed_response}")
            
            fields = parsed_response.strip('*').strip('!').split('=')
            if len(fields) < 2:
                raise ValueError(f"Incomplete status response: {parsed_response}")
            
            status_fields = fields[1].split(',')
            if len(status_fields) < 7:
                raise ValueError(f"Incomplete status fields: {status_fields}")
            
            status = {
                # 'time': status_fields[0],
                # 'temperature': int(status_fields[1]),
                # 'process_status': int(status_fields[2]),
                # 'heater_status': int(status_fields[3]),
                # 'error_code': int(status_fields[4]),
                # 'warning_code': int(status_fields[5]),
                # 'sensor_status': int(status_fields[6]),
                # 'heating_time': int(status_fields[7])
                # 'time': status_fields[0],
                'temperature': int(status_fields[0]),
                'process_status': int(status_fields[1]),
                'heater_status': int(status_fields[2]),
                'error_code': int(status_fields[3]),
                'warning_code': int(status_fields[4]),
                'sensor_status': int(status_fields[5]),
                'heating_time': int(status_fields[6])
            }
            
            print(f"[DEBUG] Parsed device status: {status}")
            return status
        except Exception as e:
            print(f"[ERROR] Error parsing device status: {e}")
            return None

    def is_ready_for_sealing(self, target_temperature):
        """
        检查设备是否准备好进行封膜操作。
        
        :param target_temperature: 目标封膜温度
        :return: 是否准备好
        """
        try:
            status = self.get_device_status()
            if status is None:
                print("[ERROR] Failed to retrieve device status.")
                return False
            
            if status['error_code'] != 0:
                print(f"[ERROR] Device has error: {status['error_code']}")
                return False
            if status['temperature'] < target_temperature:
                print(f"[ERROR] Current temperature ({status['temperature']}°C) is below target ({target_temperature}°C).")
                return False
            if status['heater_status'] not in [0, 1, 2]:  # Heater is ready or heating
                print(f"[ERROR] Heater is not ready (status: {status['heater_status']}).")
                return False
            
            print("[INFO] Device is ready for sealing.")
            return True
        except Exception as e:
            print(f"[ERROR] Error checking device readiness: {e}")
            return False

    def is_sealing_complete(self):
        """
        检查封膜过程是否完成。
        
        :return: 是否完成
        """
        try:
            status = self.get_device_status()
            if status is None:
                print("[ERROR] Failed to retrieve device status.")
                return False
            
            if status['process_status'] == 4 or status['process_status'] == 0:  # Status 4 indicates completion
                print("[INFO] Sealing process is complete.")
                return True
            else:
                print(f"[INFO] Sealing process is not complete (current status: {status['process_status']}).")
                return False
        except Exception as e:
            print(f"[ERROR] Error checking sealing completion: {e}")
            return False

    def close(self):
        """关闭串口连接"""
        self.ser.close()

    def set_sealing_time(self, seconds):
        """
        设置封膜时间。
        
        :param seconds: 封膜时间（秒），范围需符合设备要求
        """
        if 1 <= seconds <= 999:  # 假设时间范围在1到999秒之间
            formatted_time = f"{seconds:04d}"  # 格式化为4位数字
            print("[INFO] Setting sealing time...")
            self.send_command(command="DT", params=[formatted_time])
        else:
            raise ValueError("Sealing time out of range. Must be between 1 and 999.")

    def set_sealing_temperature(self, temperature):
        """
        设置封膜温度。
        
        :param temperature: 封膜温度（度），范围需符合设备要求
        """
        if 100 <= temperature <= 200:  # 假设温度范围在100到200度之间
            formatted_temp = f"{temperature:04d}"  # 格式化为4位数字
            print("[INFO] Setting sealing temperature...")
            self.send_command(command="DH", params=[formatted_temp])
        else:
            raise ValueError("Temperature out of range. Must be between 100 and 200.")

    def start_sealing(self):
        """开始封膜操作"""
        print("[INFO] Starting sealing operation...")
        self.send_command(command="GS")